using System;
using System.Windows;
using System.Windows.Controls;
using WPFTemplateLib.WpfHelpers;

namespace WPFTemplateLib.Attached
{
	/// <summary>
	/// 通过目标的 RenderTransformOrigin 来定位自身
	/// </summary>
	public class LocationTargetRenderOriginAttached
	{
		#region 附加属性

		#region [附加属性] 目标元素
		public static FrameworkElement GetTargetElement(DependencyObject obj)
		{
			return (FrameworkElement)obj.GetValue(TargetElementProperty);
		}
		/// <summary>
		/// 目标元素
		/// </summary>
		public static void SetTargetElement(DependencyObject obj, FrameworkElement value)
		{
			obj.SetValue(TargetElementProperty, value);
		}
		/// <summary>
		/// [附加属性] 目标元素
		/// </summary>
		public static readonly DependencyProperty TargetElementProperty =
			DependencyProperty.RegisterAttached("TargetElement", typeof(FrameworkElement), typeof(LocationTargetRenderOriginAttached), new PropertyMetadata(null, TargetElementChangedCallback));
		/// <summary>
		/// 目标元素变化
		/// </summary>
		private static void TargetElementChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			RefreshLocation(d);
		}
		#endregion

		#region [附加属性] 是否翻转原点
		public static bool GetIsFlipOrigin(DependencyObject obj)
		{
			return (bool)obj.GetValue(IsFlipOriginProperty);
		}
		/// <summary>
		/// 是否翻转原点
		/// </summary>
		public static void SetIsFlipOrigin(DependencyObject obj, bool value)
		{
			obj.SetValue(IsFlipOriginProperty, value);
		}
		/// <summary>
		/// [附加属性] 是否翻转原点
		/// </summary>
		public static readonly DependencyProperty IsFlipOriginProperty =
			DependencyProperty.RegisterAttached("IsFlipOrigin", typeof(bool), typeof(LocationTargetRenderOriginAttached), new PropertyMetadata(false, IsFlipOriginChangedCallback));
		private static void IsFlipOriginChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			RefreshLocation(d);
		}
		#endregion

		#region [附加属性] 是否将被附加的元素中心点与目标元素的渲染原点对齐（默认 true）
		public static bool GetIsAlignWithCenter(DependencyObject obj)
		{
			return (bool)obj.GetValue(IsAlignWithCenterProperty);
		}
		/// <summary>
		/// 设置 是否将被附加的元素中心点与目标元素的渲染原点对齐（默认 true）
		/// </summary>
		public static void SetIsAlignWithCenter(DependencyObject obj, bool value)
		{
			obj.SetValue(IsAlignWithCenterProperty, value);
		}
		/// <summary>
		/// [附加属性] 是否将被附加的元素中心点与目标元素的渲染原点对齐
		/// </summary>
		public static readonly DependencyProperty IsAlignWithCenterProperty =
			DependencyProperty.RegisterAttached("IsAlignWithCenter", typeof(bool), typeof(LocationTargetRenderOriginAttached), new PropertyMetadata(true, IsAlignWithCenterChangedCallback));
		/// <summary>
		/// 是否将被附加的元素中心点与目标元素的渲染原点对齐 变化处理方法
		/// </summary>
		private static void IsAlignWithCenterChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			RefreshLocation(d);
		}
		#endregion

		#endregion

		#region 方法

		/// <summary>
		/// 刷新定位
		/// </summary>
		private static void RefreshLocation(DependencyObject d)
		{
			var element = d as FrameworkElement; //当前元素
			var targetElement = GetTargetElement(element); //目标元素
			if(element == null || targetElement == null)
				return;

			bool isFlipOrigin = GetIsFlipOrigin(d);
			bool isAlignWithCenter = GetIsAlignWithCenter(d);
			var originPoint = targetElement.GetRenderTransformOriginPointInCanvas(out _, isFlipOrigin);

			double elementWidth = Math.Max(element.ActualWidth, element.Width);
			double elementHeight = Math.Max(element.ActualHeight, element.Height);
			double left = isAlignWithCenter ? originPoint.X - elementWidth / 2.0 : originPoint.X;
			double top = isAlignWithCenter ? originPoint.Y - elementHeight / 2.0 : originPoint.Y;

			Canvas.SetLeft(element, left);
			Canvas.SetTop(element, top);
		}

		#endregion
	}
}
